﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using OestsCommon.TcpNet;
using OestsServer.Handlers;
using OestsServer.Managers;
using Utils;

namespace OestsServer.Net
{
	/// <summary>
	/// tcp通讯类(服务器)
	/// </summary>
	public class Server
	{
		private int _port = 7788;
		private Socket serverSocket;
		private Dictionary<PacketKey, HandlerBase> dictPacketHandlers = new Dictionary<PacketKey, HandlerBase>();
		//存错误的信息
		public static List<string> listError = new List<string>();

		#region 单列
		private static Server _instance;
		public static Server Instance
		{
			get
			{
				if (_instance == null)
					_instance = new Server();
				return _instance;
			}
		}

		public Server()
		{
			_instance = this;
			RegisteHandler();
		}
		#endregion


		/// <summary>
		/// 启动服务器
		/// </summary>
		public void Start()
		{
			serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			//获取本机IP
			string HostName = Dns.GetHostName();
			IPHostEntry IpEntry = Dns.GetHostEntry(HostName); //得到主机IP	
			IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
			for (int i = 0; i < IpEntry.AddressList.Length; i++)
			{
				if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
				{
					ipAddress = IpEntry.AddressList[i];
					break;
				}
			}
			serverSocket.Bind(new IPEndPoint(ipAddress, _port));
			serverSocket.Listen(100);
			serverSocket.BeginAccept(AcceptCallBack, null);
			Program.startStr = "---" + DateTime.Now.ToString("HH:mm:ss") + " - 服务器启动 - ip:" + IPAddress.Parse(ipAddress.ToString());
			DateTime.Now.ToString("T");
			Console.WriteLine(Program.startStr);
			Console.WriteLine("---------------------------------------------------------------");

		}

		private void AcceptCallBack(IAsyncResult asyncResult)
		{
			Socket clientSocket = serverSocket.EndAccept(asyncResult);
			ClientChannel client = new ClientChannel(this, clientSocket);//把与每个客户端通信的逻辑(收发消息)放到client类里面进行处理
			ClientManager.Instance.AddClient(client);

			string userIP = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
			Console.WriteLine(string.Format("a client({0}) is connected !", userIP));

			serverSocket.BeginAccept(AcceptCallBack, null);
		}


		public HandlerBase GetHandler(PacketKey packetKey)
		{
			if (dictPacketHandlers.ContainsKey(packetKey))
			{
				return dictPacketHandlers[packetKey];
			}
			return null;
		}

		/// <summary>
		/// 解析数据包处理
		/// </summary>
		/// <param name="client"></param>
		/// <param name="data"></param>
		public void Parse(ClientChannel client, Request packet)
		{
			if (dictPacketHandlers.ContainsKey(packet.RequestCode))
			{
				HandlerBase handler = dictPacketHandlers.TryGet(packet.RequestCode);

                try
                {
                    handler.Execute(client, packet);
                    // client.Send(handler.ResponsePacket);
                }
                catch (Exception)
                {
                    //捕获处理器处理时发生的异常
                    throw;
                }
			
				
			}
			else
			{
				string str = "---- : “" + packet.RequestCode + "”-未注册！ ";
				listError.Add(str);
				Console.WriteLine(str);

			}
		}

		/// <summary>
		/// 自动注册所有的处理类
		/// </summary>
		public void RegisteHandler()
		{
			Type[] types = Assembly.GetAssembly(typeof(HandlerBase)).GetTypes();
			foreach (var type in types)
			{
				if (type.FullName.EndsWith("Handler"))
				{
					Activator.CreateInstance(type);
				}
			}
		}
		public void AddHandler(PacketKey key, HandlerBase handler)
		{
			if (dictPacketHandlers.ContainsKey(key))
			{
				Console.WriteLine("注册 HandlerBase 错误，" + key.ToString() + " 已经被注册！");
			}
			else
			{
				dictPacketHandlers.Add(key, handler);
			}
		}
	}
}